package cn.xiaolang;

/**
 * this指针逃逸
 * （1）在构造器中很明显地抛出this引用提供其他线程使用（如上述的明显将this抛出）。
 * （2）在构造器中内部类使用外部类情况：内部类访问外部类是没有任何条件的，也不要任何代价，
 *  也就造成了当外部类还未初始化完成的时候，内部类就尝试获取为初始化完成的变量
 *
 * @author Dean
 * @date 2021-04-27
 */
public class ThisEscapeSample {

    //final常量会保证在构造器内完成初始化（但是仅限于未发送this逃逸的情况下）
    final int i;
    //尽管实例变量有初始值，但是还未实例化完成
    int j = 0;
    static ThisEscapeSample obj;

    public ThisEscapeSample() {
        i = 1;
        j = 1;
        obj = this;
    }

    public static void main(String[] args) {
        //读取对象引用，访问i/j变量
        new Thread(() -> {
            //可能会发生初始化失败的情况解释：实例变量i的初始化被重排序到构造器外，此时1还未被初始化
            ThisEscapeSample objB = obj;
            try {
                System.out.println(objB.j);
            } catch (NullPointerException e) {
                System.out.println("发生空指针错误：普通变量j未被初始化");
            }
            try {
                System.out.println(objB.i);
            } catch (NullPointerException e) {
                System.out.println("发生空指针错误：final变量i未被初始化");
            }
        }).start();
    }
}


